package jNotesGUI;

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.util.ArrayList;

import javax.swing.*;
import com.sun.java.swing.plaf.windows.WindowsBorders.ToolBarBorder;
import jNotesUtilities.Load_Save;

import org.digitalmonks.automenu.*;
import org.digitalmonks.automenu.control.events.AAutoMenuEvent;
import org.digitalmonks.automenu.control.events.AAutoMenuListener;

public class Main extends JFrame implements ActionListener
{
	static Main f;

	/**
	 * 
	 */
	private static final long serialVersionUID = 2545398382631729562L;

	/**
	 * This is the string that will contain the version number that will be shown on every window.
	 * A standard numbering system needs to be assign in order to maintain versioning consistency.
	 */
	final static String Version = "0.0.2.1 Alpha";
	
	/**
	 * Boolean variable used to maintain a control in sensible variables.
	 * Note: This must only be modified by methods actually needing it, as this is here as a security mesure.
	 * This must also be set to false at the end of the usage.
	 */
	private boolean Access = false;
	
	/**
	 * Keeps track of the notes in the Array. this is also used as an ID assigner for the jNotesCore.Note Class.
	 * This should remain private to avoid any other class from modifiyng this number as it could cause serious errors.
	 */
	private int NoteIndex = 0;
	
	/**
	 * Main Panel Containing all the notes attached.
	 */
	JPanel Panel = new JPanel();
	
	final private String xmlFileLocation = "test.xml";
	
	/**
	 * Main Menu Bar
	 */
	JMenuBar bar = new JMenuBar();
	
	JMenu File = null;
	JMenuItem File_NewNoteArchive = null;
	JMenuItem File_InsertNote = null;
	JMenuItem File_ImportArchives = null;
	JMenuItem File_Export = null;
	JMenuItem File_Backup = null;
	JMenuItem File_Exit = null;
	
	JMenu Edit = null;
	JMenuItem Edit_Cut = null;
	JMenuItem Edit_Copy = null;
	JMenuItem Edit_Paste = null;
	JMenuItem Edit_Preferences = null;
	
	JMenu Help = null;
	JMenuItem Help_Help_Contents = null;
	JMenuItem Help_About = null;
	
	ABarMenu Menu = null;
	
	Menu menuBar;
	
	PopupMenu rightClickPanel;
	
	InputMap File_InsertNote_inputMap;
	InputMap File_Exit_inputMap;
	
	
	JScrollPane Scroll;
	
	Image iconImage;
	
	
	/**
	 * Used to create the margins in the notes.
	 * 
	 * NOTE:
	 * The following is for reference to modifying this method:
	 * 	Insets Arguments for Margins are as Follows: 
	 * 		(top, left, bottom, right)
	 * 
	 */
	Insets m = new Insets(0, 15, 0, 0);
	
	ArrayList<JTextArea> TextContainer = new ArrayList<JTextArea>();
	ArrayList<JButton> Notes = new ArrayList<JButton>();
	
	ArrayList<NoteListener> nListen = new ArrayList<NoteListener>();
	PanelListener pListen = new PanelListener(this);
	
	NoteContainer Container;
	
	Thread ContainerThread;
	
	InputMap test;
	
	Load_Save a = new Load_Save();
	
	public Main(String title)
	{
		super(title);
		
		
		
		Panel.setLayout(null);
		
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		
		init();//Initialize the window
		
		makeMenu();//Create all the menus structure
		
		this.setJMenuBar(bar);//Show the menu
		
		makeToolbar();//Create the toolbar
		
		this.setVisible(true);//Show the window
		
		Container = new NoteContainer(this, Notes, TextContainer);
		
		ContainerThread = new Thread(Container);
		//Panel.add(rightClickPanel);
		ContainerThread.run();
	}
	
	/**
	 * All the processes needed before starting the GUI.
	 */
	private void init()
	{
		final Container window = this.getContentPane();

		final Point initialLocation = new Point(100, 100);

		//window.setLayout(new BorderLayout());
		
		Scroll = new JScrollPane(Panel);
		
		
		
		Panel.addMouseListener(pListen);
		
		//this.add(Panel);
		
		addNote();
		addNote(new Point(200, 100));
		addNote(new Point(400, 100));
		addNote();
		
		window.add(Notes.get(0));
		
		window.add(Scroll);
		
		
		this.setSize(800, 600);
		
		this.setLocation(initialLocation);
		
		//menuBar.sendMain(f);//Send self to Menu Listener
	}
	
	/**
	 * Create all the menus.
	 */
	private void makeMenu()
	{
		menuBar = new Menu();
		
		bar.add(menuBar.File);
		bar.add(menuBar.Edit);
		bar.add(menuBar.Help);
	}
	
	/**
	 * Create the Toolbar
	 */
	private void makeToolbar()
	{
		this.makeToolbarButton("Save", "Save", "Save the opened archive", "Save");
	}
	
	

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	//GUI Helper Methods
	/**
	 * Makes a JButton with the selected parameters
	 */
	private JButton makeToolbarButton(final String imageName,
			final String actionCommand, final String toolTipText,
			final String altText)
	{
		// Look for the image.
		final String imgLocation = "/Pictures/" + imageName + ".png";
		final URL imageURL = ToolBarBorder.class.getResource(imgLocation);

		// Create and initialize the button.
		final JButton button = new JButton();
		button.setActionCommand(actionCommand);
		button.setToolTipText(toolTipText);
		button.addActionListener(this);

		if (imageURL != null)
		{
			button.setIcon(new ImageIcon(imageURL, altText));
		}
		else
		{
			button.setText(altText);
			System.err.println("Resource not found: " + imgLocation);
		}

		return button;
	}
	
	/**
	 * Creates a new note on the GUI with all the default settings
	 */
	public void addNote()
	{
		this.remove(Scroll);
		
		TextContainer.add(new JTextArea(""));
		
		TextContainer.get(NoteIndex).setLineWrap(true);
		
		Notes.add(new JButton());
		
		Notes.get(NoteIndex).add(TextContainer.get(NoteIndex));
		
		Notes.get(NoteIndex).setText("Move");
		Notes.get(NoteIndex).setSize(100, 30);
		Notes.get(NoteIndex).setLocation(500, 100);
		
		nListen.add(new NoteListener(Notes.get(NoteIndex), this));
		
		Notes.get(NoteIndex).addMouseMotionListener(nListen.get(NoteIndex));
		Notes.get(NoteIndex).setMargin(m);
		
		
		Panel.add(Notes.get(NoteIndex));
		
		this.repaint();
		this.add(Scroll);
		TextContainer.get(NoteIndex).repaint();
		
		Notes.get(NoteIndex).setSize(100, 30);
		TextContainer.get(NoteIndex).addPropertyChangeListener(nListen.get(NoteIndex));
		TextContainer.get(NoteIndex).addPropertyChangeListener("PreferredSize", nListen.get(NoteIndex));
		
		Notes.get(NoteIndex).setMaximumSize(new Dimension(200, 90));
		
		NoteIndex++;
		
		
		//NOTE: DO NOT REMOVE THE FOLLOWING 2 LINES OF CODE
		//This is used to update whenever a new note is added so 
		//that the button isn't displayed without text. This should be 
		//fixed by another way if possible but has low priority.
		TextContainer.get(0).setText(TextContainer.get(0).getText() + "\n");
		TextContainer.get(0).setText(TextContainer.get(0).getText().substring(0, TextContainer.get(0).getText().lastIndexOf("\n")));
		Panel.repaint();
	}
	
	/**
	 * Creates a new note but specifies the Location in witch to put it.
	 * @param Location - Location of the new note
	 */
	public void addNote(Point Location)
	{
		addNote();
		Notes.get(NoteIndex-1).setLocation(Location);
	}
	
	public void removeNote(int ID)
	{
		Notes.remove(ID);
		TextContainer.remove(ID);
		NoteIndex--;
	}
	
	public int getNoteIndex() 
	{
		return NoteIndex;
	}
	
	public boolean isAccesing() 
	{
		return Access;
	}
	
	public static void showAbout()
	{
		/**
		 * Message to appear on the about pop-up
		 */
		String msg = "jNotes v." + Main.Version + "\nCopyright Andres Ruiz 2008-2009" + "\n" + "This program is licenced under the GPL, \nfor licence details please see the licence.txt \nshiped with this program";
	
		JOptionPane.showMessageDialog(null, msg, "About", JOptionPane.INFORMATION_MESSAGE);
	}
	
	
	//Close Override
	public void dispose()
	{
		final int Dialog = JOptionPane.showConfirmDialog(null,
				"You will lose any unsaved work.\nQuit?", "Quit?",
				JOptionPane.YES_NO_OPTION);
		
		Container.exitNow = true;
		
		
		if (Dialog == 0)
			super.dispose();
	}
	
	
	
	
	
	
	
	
	
	
	
	//Action Listener
	public void actionPerformed(ActionEvent event) 
	{
		String Event = event.getActionCommand();
		
		if(Event.equalsIgnoreCase("Exit"))
			this.dispose();
		else if(Event.equalsIgnoreCase("Save"))
			this.a.Save();
		else if(Event.equalsIgnoreCase("Load"))
			this.a.Load();
		else if(Event.equalsIgnoreCase("New Note"))
			addNote();
		else if(Event.equalsIgnoreCase("About"))
			showAbout();
	}
	
	
	//KeyListener
	
	public void keyPressed(KeyEvent e) 
	{
		System.out.println(e.getKeyChar() + " Key Pressed");
		
		if(KeyEvent.VK_INSERT == e.getKeyChar())
			addNote();
		else if(e.isControlDown() && e.getKeyChar() == 'q')
			dispose();
	}
	
	public void keyReleased(KeyEvent e) 
	{
		System.out.println("Key Released");
	}

	public void keyTyped(KeyEvent e) 
	{
		System.out.println("Key Typed");
	}
	
	public static void main(String[] args) 
	{
		final String title = "jNotes" + " v." + Version;

		f = new Main(title);
		
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		
	}

	public boolean dispatchKeyEvent(KeyEvent e) 
	{
		System.out.println("Key event Dispached");
		return false;
	}
}
